﻿using Communergy.Repository;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Communergy.Common;
using System.Collections.Generic;
using System;
using Communergy.UnitTesting;
using Communergy.Repository.SQLite;
using System.Linq;

namespace Communergy.Repository.SQLite.Tests
{
    
    
    
    /// <summary>
    ///This is a test class for SQLiteRealtimeRepositoryTest and is intended
    ///to contain all SQLiteRealtimeRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SQLiteRealtimeRepositoryTest
    {
		#region Fields (1) 

        private TestContext testContextInstance;
        IUnitOfWork sqliteUnitOfWork;
        SQLiteRealtimeRepository sqliteRepository;

        const string METERID = "1";
        const int WATTS = 123;
        const int JOULES = 500;


		#endregion Fields 

		#region Properties (1) 

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

		#endregion Properties 

		#region Methods (1) 

		// Public Methods (1) 
        //[ClassInitialize()]
        
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}

        [TestInitialize()]        
        public void MyTestInitialize()
        {
            string connectionString = ConfigurationHelper.SqliteConnectionString(ConfigurationHelper.SQLLitePath);
            CommunergySQLiteEntities sqlite = new CommunergySQLiteEntities(connectionString);
            foreach (var realtime in sqlite.ElectricityRealtime)
            {
                sqlite.DeleteObject(realtime);
            }
            sqlite.SaveChanges();
            sqliteUnitOfWork = (CommunergySQLiteEntities)sqlite;
            sqliteRepository = new SQLiteRealtimeRepository(sqliteUnitOfWork);
            

        }
        /// <summary>
        ///A test for Insert_ElectricityRealtime
        ///</summary>
        [TestMethod()]
        [DeploymentItem(@"..\Database\SQLite\Communergy.s3db")]
        public void SQLLite_InsertElectricityRealtimeTest_CheckInserted()
        {
            string meterId = METERID;
            List<RealtimeEnergyReading> realtimeEnergyReadings = GetTestRealtimeRecordToInsert() ;
            
            sqliteRepository.Insert_ElectricityRealtime(meterId, realtimeEnergyReadings);
            sqliteUnitOfWork.Save();
            var getReadings = sqliteRepository.Get_ElectricityRealtime(meterId, DateTime.Now.AddDays(-1), DateTime.Now.AddDays(1));

            Assert.AreEqual(1, getReadings.Count);

        }

        [TestMethod()]
        [DeploymentItem(@"..\Database\SQLite\Communergy.s3db")]
        public void SQLLite_InsertElectricityRealtimeTest_CheckWatts()
        {
            string meterId = METERID;
            List<RealtimeEnergyReading> realtimeEnergyReadings = GetTestRealtimeRecordToInsert();

            sqliteRepository.Insert_ElectricityRealtime(meterId, realtimeEnergyReadings);
            sqliteUnitOfWork.Save();
            var getReadings = sqliteRepository.Get_ElectricityRealtime(meterId, DateTime.Now.AddDays(-1), DateTime.Now.AddDays(1));

            var reading = getReadings.First();
            Assert.AreEqual(JOULES, reading.Joules);
        }

        [TestMethod()]
        [DeploymentItem(@"..\Database\SQLite\Communergy.s3db")]
        public void SQLLite_InsertElectricityRealtimeTest_CheckJoules()
        {
            string meterId = METERID;
            List<RealtimeEnergyReading> realtimeEnergyReadings = GetTestRealtimeRecordToInsert();

            sqliteRepository.Insert_ElectricityRealtime(meterId, realtimeEnergyReadings);
            sqliteUnitOfWork.Save();
            var getReadings = sqliteRepository.Get_ElectricityRealtime(meterId, DateTime.Now.AddDays(-1), DateTime.Now.AddDays(1));

            var reading = getReadings.First();

            Assert.AreEqual(JOULES, reading.Joules);
        }

        /// <summary>
        ///A test for GetCumulativeElectricityRealtime
        ///</summary>
        [TestMethod()]
        [DeploymentItem(@"..\Database\SQLite\Communergy.s3db")]
        public void SQLLite_GetCumulativeElectricityRealtimeForExpectedData_CheckKwh()
        {
            string meterId = METERID;
            List<RealtimeEnergyReading> realtimeEnergyReadings = GetTestRealtimeRecordsForCumulative();

            sqliteRepository.Insert_ElectricityRealtime(meterId, realtimeEnergyReadings);
            sqliteUnitOfWork.Save();

            DateTime dateFrom = DateTime.Now.AddHours(-1);
            DateTime dateTo = DateTime.Now.AddHours(1);

            decimal expectedKWh = 0.029166667M;


            HistoricalEnergyReading returnedCumulative = sqliteRepository.GetCumulativeElectricityRealtime(meterId, dateFrom, dateTo);
            Assert.AreEqual(Math.Round(expectedKWh,6), Math.Round(returnedCumulative.KWh,6));
            
        }



        /// <summary>
        ///A test for GetCumulativeElectricityRealtime
        ///</summary>
        [TestMethod()]
        [DeploymentItem(@"..\Database\SQLite\Communergy.s3db")]
        public void SQLLite_GetCumulativeElectricityRealtimeForNoRecords_ReturnsNull()
        {
            string meterId = METERID;          
            DateTime dateFrom = DateTime.Now.AddYears(1);
            DateTime dateTo = DateTime.Now.AddYears(10);        


            HistoricalEnergyReading returnedCumulative = sqliteRepository.GetCumulativeElectricityRealtime(meterId, dateFrom, dateTo);
            Assert.IsNull(returnedCumulative);
        }


        private static List<RealtimeEnergyReading> GetTestRealtimeRecordToInsert()
        {

            var realtimeEnergyReading = new RealtimeEnergyReading { ReadingDateTime = DateTime.Now, Watts = WATTS, Joules = JOULES };
            var realtimeEnergyReadings = new List<RealtimeEnergyReading>();
            realtimeEnergyReadings.Add(realtimeEnergyReading);
            return realtimeEnergyReadings;
        }

        private static List<RealtimeEnergyReading> GetTestRealtimeRecordsForCumulative()
        {
            var realtimeEnergyReadings = new List<RealtimeEnergyReading>();
            DateTime baseDateTime = DateTime.Now;

            for (int i = 1; i <= 20; i++)
            {

                var realtimeEnergyReading = new RealtimeEnergyReading {
                    ReadingDateTime = baseDateTime.AddMinutes(i), 
                    Watts = WATTS * i,
                    Joules = JOULES * i
                };
                realtimeEnergyReadings.Add(realtimeEnergyReading);
            }           
           
            
            return realtimeEnergyReadings;
        }

		#endregion Methods 
        



    }
}
